package afcp.alumni.model.db;

//import javax.persistence.Basic;
//import javax.persistence.Column;
//import javax.persistence.Column;
import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import afcp.alumni.model.base.SAPIEntity;
import afcp.alumni.model.base.UniqueField;
import afcp.alumni.model.base.WithUniqueField;
import afcp.alumni.security.PasswordEncoder;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.search.Document;
import com.google.appengine.api.search.Field;
import com.google.appengine.datanucleus.annotations.Unowned;

/**
 * <p>
 * Objet métier représentant un utilisateur identifié sur le site.
 * </p>
 * <p>
 * Implémente {@link Serializable} pour stocker l'utilisateur authentifié en
 * variable de session.
 * </p>
 * 
 * @author Antoine
 * 
 */
//@NamedQuery(name = "Member.findAll", query = "SELECT m FROM Member m")
@PersistenceCapable
public class Member implements SAPIEntity, Serializable, WithUniqueField {
 
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static final String COL_FIRSTNAME = "firstName";
	public static final String COL_LASTNAME = "lastName";
	public static final String COL_LOGIN = "login";
	public static final String COL_PASSWORD = "password";
	public static final String COL_SEX = "login";
	public static final String COL_CHINESE_NAME = "chineseName";
	public static final String COL_BIRTH_DATE = "birthDate";
	public static final String COL_COUNTRY = "country";
	public static final String COL_EMAIL = "email";
	public static final String COL_PHONE = "phone";
	public static final String COL_WEIBO = "weibo";
	public static final String COL_WEIXIN = "weixin";
	public static final String COL_PARISTECH_ENTRANCE_YEAR = "parisTechEntranceYear";
	public static final String COL_PARISTECH_SCHOOL = "parisTechSchool";
	public static final String COL_CHINESE_UNIVERSITY = "chineseUniversity";
	public static final String COL_EMPLOYER = "employer";
	public static final String COL_CURRENT_JOB_COUNTRY = "currentJobCountry";
	public static final String COL_JOB = "job";

	public static final CsvColumn[] defaultColumns = new CsvColumn[] {
			new CsvColumn(COL_FIRSTNAME, "firstName", "Prénom 名（拼音）"),
			new CsvColumn(COL_LASTNAME, "lastName", "Nom 姓（拼音）"),
			new CsvColumn(COL_LOGIN, "login", "Identifiant"),			//TODO
			new CsvColumn(COL_PASSWORD, "password", "Mot de passe"),	//TODO
			new CsvColumn(COL_SEX, "sex", "Sex 性别"),
			new CsvColumn(COL_CHINESE_NAME, "chineseName", "Nom Chinois 中文姓名"),
			new CsvColumn(COL_BIRTH_DATE, "birthDate", "Date de naissance 出生日期 (cf. 31/12/2012)"),
			new CsvColumn(COL_COUNTRY, "country", "Pays de résidance 居住国"),
			new CsvColumn(COL_EMAIL, "email", "Email 电子邮箱"),
			new CsvColumn(COL_PHONE, "phone", "Téléphone 电话 (cf. +33 06 XX XX XX XX)"),
			new CsvColumn(COL_WEIBO, "weibo", "WeiBo （微博）(Optional)"),
			new CsvColumn(COL_WEIXIN, "weixin", "WeiXin (微信)(Optional)"),
			new CsvColumn(COL_PARISTECH_ENTRANCE_YEAR, "parisTechEntranceYear", "Année d'entrée à ParisTech 入学巴黎高科年份"),
			new CsvColumn(COL_PARISTECH_SCHOOL, "parisTechSchool", "Ecole ParisTech 所属巴黎高科学校"),
			new CsvColumn(COL_CHINESE_UNIVERSITY, "chineseUniversity", "Université en Chine 所属国内大学"),
			new CsvColumn(COL_EMPLOYER, "employer", "Employeur actuelle 现雇主"),
			new CsvColumn(COL_CURRENT_JOB_COUNTRY, "currentJobCountry", "Pays de l'emploi actuel 现工作所在国"),
			new CsvColumn(COL_JOB, "job", "Métier 职业")
			};
	
	public enum Sex {
		MALE, FEMALE
	}

	public Member() {
	}

	// @GeneratedValue(strategy=GenerationType.IDENTITY)
	@PrimaryKey
	@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) // To allow automatic
	// generation when saving to datastore
	private Key key;

	@Override
	public Key getKey() {
		return key;
	}

	/**
	 * Don't call this method because Member has no
	 */
	@Override
	public void setKeyWithAncestor(Key ancestorKey) {
//		this.key = KeyFactory.createKey(ancestorKey, this.getClass().getSimpleName(), id);

		// do nothing: automatically generated.
	}

	@Override
	public String getId() {
		return key == null ? null : KeyFactory.keyToString(key);
	}
//	public void setId(String id) {
//		this.login = id;
//	}
	
	@Override
	public String toString() {
		return login.getId();
	}


	@Persistent
	@Unowned
	private Login login;
	// @Basic
	@Persistent
	private String firstName;
	// @Basic
	// @Column(name="lastName")
	@Persistent
	private String lastName;
	@Persistent
	private String password;
//	@OneToMany(cascade = CascadeType.ALL)
	@Persistent
	@Unowned
	private List<Role> roles;
	@Persistent
	private boolean deletable = true;
	@Persistent
	private Sex sex;
	@Persistent
	private String chineseName;
	@Persistent
	private Date birthDate;
	@Persistent
	private String country;
	@Persistent
	private String email; // Obligatoire
	@Persistent
	private String phone; // Avec une regex ? Pas sûr car ça ne doit pas empêcher l'ajout en BDD depuis le fichier
	@Persistent
	private String weibo;
	@Persistent
	private String weixin;
	@Persistent
	private int parisTechEntranceYear;
	@Persistent
	private String parisTechSchool;
	@Persistent
	private String chineseUniversity;
	@Persistent
	private String employer;
	@Persistent
	private String currentJobCountry;
	@Persistent
	private String job;
	
	
	

	public Login getLogin() {
		return login;
	}

	public void setLogin(Login login) {
		this.login = login;
	}

	public Sex getSex() {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}

	public String getChineseName() {
		return chineseName;
	}

	public void setChineseName(String chineseName) {
		this.chineseName = chineseName;
	}

	public Date getBirthDate() {
		return birthDate;
	}

	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getWeibo() {
		return weibo;
	}

	public void setWeibo(String weibo) {
		this.weibo = weibo;
	}

	public String getWeixin() {
		return weixin;
	}

	public void setWeixin(String weixin) {
		this.weixin = weixin;
	}

	public int getParisTechEntranceYear() {
		return parisTechEntranceYear;
	}

	public void setParisTechEntranceYear(int parisTechEntranceYear) {
		this.parisTechEntranceYear = parisTechEntranceYear;
	}

	public String getParisTechSchool() {
		return parisTechSchool;
	}

	public void setParisTechSchool(String parisTechSchool) {
		this.parisTechSchool = parisTechSchool;
	}

	public String getChineseUniversity() {
		return chineseUniversity;
	}

	public void setChineseUniversity(String chineseUniversity) {
		this.chineseUniversity = chineseUniversity;
	}

	public String getEmployer() {
		return employer;
	}

	public void setEmployer(String employer) {
		this.employer = employer;
	}

	public String getCurrentJobCountry() {
		return currentJobCountry;
	}

	public void setCurrentJobCountry(String currentJobCountry) {
		this.currentJobCountry = currentJobCountry;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public void setRole(Role role) {
		this.roles = new LinkedList<Role>();
		this.roles.add(role);
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = PasswordEncoder.hash(password);
	}

	public boolean isDeletable() {
		return deletable;
	}

	public void setDeletable(boolean deletable) {
		this.deletable = deletable;
	}

	// TODO compléter avec les champs recherchables.
	@Override
	public Document getDocument() {
		return Document
				.newBuilder()
				.setId(this.getId())
				.addField(
						Field.newBuilder().setName("firstName")
								.setText(this.getFirstName()))
				.addField(
						Field.newBuilder().setName("lastName")
								.setText(this.getLastName())).build();
	}

	@Override
	public Document getDocumentWithIdOnly() {
		return Document.newBuilder().setId(this.getId()).build();
	}

	@Override
	public UniqueField<Member> getUniqueField() {
		return login;
	}
	
}
